package com.koko.controller;

import com.github.pagehelper.Page;
import com.koko.feign.AdminFeignService;
import com.koko.feign.GameFeignService;
import com.koko.game.dto.GamePageQueryDTO;
import com.koko.game.dto.PublisherPageQueryDTO;
import com.koko.game.entity.Game;
import com.koko.game.entity.Publisher;
import com.koko.game.vo.GameAdminPageItemVO;
import com.koko.news.dto.NewsDTO;
import com.koko.news.dto.NewsPageQueryDTO;
import com.koko.news.entity.News;
import com.koko.news.vo.NewsDetailVO;
import com.koko.news.vo.NewsVO;
import com.koko.result.PageResult;
import com.koko.result.Result;
import com.koko.service.NewsService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/news")
public class NewsController {
    @Autowired
    private NewsService newsService;
    @Autowired
    private GameFeignService gameFeignService;
    @Autowired
    private AdminFeignService adminFeignService;

    @GetMapping("/admin/page")
    @Cacheable(value = "newsCache", key = "'newsPage'")
    public PageResult<NewsVO> newsManagementPageQuery(NewsPageQueryDTO newsPageQueryDTO) {
        PageResult<NewsVO> pageResult = new PageResult<>();
        if (newsPageQueryDTO.getPublisherNameOrGameName() != null && !newsPageQueryDTO.getPublisherNameOrGameName().isEmpty()) {
            // 1. 查询发行商
            PublisherPageQueryDTO publisherPageQueryDTO = new PublisherPageQueryDTO();
            BeanUtils.copyProperties(newsPageQueryDTO, publisherPageQueryDTO, "sort");
            publisherPageQueryDTO.setName(newsPageQueryDTO.getPublisherNameOrGameName());
            PageResult<Publisher> publisherList = gameFeignService.getPublisherList(
                    publisherPageQueryDTO.getPage(),
                    publisherPageQueryDTO.getPageSize(),
                    publisherPageQueryDTO.getName(),
                    publisherPageQueryDTO.getSort()
            );
            List<Long> publisherIds = publisherList.getRecords().stream().map((item) -> {
                return item.getId();
            }).collect(Collectors.toList());
            // 2. 查询游戏
            GamePageQueryDTO gamePageQueryDTO = new GamePageQueryDTO();
            BeanUtils.copyProperties(newsPageQueryDTO, gamePageQueryDTO, "sort");
            gamePageQueryDTO.setName(newsPageQueryDTO.getPublisherNameOrGameName());
            PageResult<Game> gameList = gameFeignService.getGameList(
                    gamePageQueryDTO.getPage(),
                    gamePageQueryDTO.getPageSize(),
                    gamePageQueryDTO.getName(),
                    gamePageQueryDTO.getSort()
            );
            List<Long> gameIds = gameList.getRecords().stream().map((item) -> {
                return item.getId();
            }).collect(Collectors.toList());
            // 3. 分页查询
            newsPageQueryDTO.setPublisherIds(publisherIds);
            newsPageQueryDTO.setGameIds(gameIds);
            Page<News> news = newsService.pageQuery(newsPageQueryDTO);
            // 4. 封装分页数据
            List<NewsVO> list = getNewsVOS(news);
            pageResult.setRecords(list);
            pageResult.setTotal(news.getTotal());
        } else {
            Page<News> news = newsService.pageQuery(newsPageQueryDTO);
            List<NewsVO> list = getNewsVOS(news);
            pageResult.setRecords(list);
            pageResult.setTotal(news.getTotal());
        }
        return pageResult;
    }

    @PostMapping("/admin")
    @CacheEvict(value = "newsCache", allEntries = true)
    public Result<String> addNews(@RequestBody NewsDTO newsDTO) {
        newsService.save(newsDTO);
        return Result.success();
    }

    @DeleteMapping("/admin")
    @CacheEvict(value = "newsCache", allEntries = true)
    public Result<String> deleteNews(@RequestBody List<Long> ids) {
        newsService.deleteBatch(ids);
        return Result.success();
    }

    @PutMapping("/admin")
    @CacheEvict(value = "newsCache", allEntries = true)
    public Result<String> updateNews(@RequestBody NewsDTO newsDTO) {
        newsService.update(newsDTO);
        return Result.success();
    }

    @GetMapping("/admin/{id}")
    @Cacheable(value = "newsCache", key = "'newsDeail' + '_' + #id")
    public Result<NewsDetailVO> getById(@PathVariable Long id) {
        News news = newsService.getById(id);
        NewsDetailVO newsDetailVO = new NewsDetailVO();
        BeanUtils.copyProperties(news, newsDetailVO);
        // 获取发行商
        Result<Publisher> publisherResult = gameFeignService.getPublisherById(news.getPublisherId());
        newsDetailVO.setPublisher(publisherResult.getData());
        // 获取游戏
        if (news.getGameId() != null) {
            Result<Game> gameResult = gameFeignService.getGameById(news.getGameId());
            newsDetailVO.setGame(gameResult.getData());
        }
        // 获取创建人、修改人
        Result<String> createAdminResult = adminFeignService.getAdminDetail(news.getCreateUserId());
        Result<String> updateAdminResult = adminFeignService.getAdminDetail(news.getUpdateUserId());
        newsDetailVO.setCreateUser(createAdminResult.getData());
        newsDetailVO.setUpdateUser(updateAdminResult.getData());
        return Result.success(newsDetailVO);
    }

    private List<NewsVO> getNewsVOS(Page<News> news) {
        List<NewsVO> list = news.getResult().stream().map((item) -> {
            NewsVO newsVO = new NewsVO();
            BeanUtils.copyProperties(item, newsVO, "content");
            newsVO.setPublisher(gameFeignService.getPublisherById(item.getPublisherId()).getData().getName());
            if (item.getGameId() != null) {
                newsVO.setGame(gameFeignService.getGameById(item.getGameId()).getData().getChineseName());
            }
            return newsVO;
        }).collect(Collectors.toList());
        return list;
    }
}
